package com.websocket;

import com.alibaba.fastjson.JSON;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;

/**
 * 处理消息的 handler
 * TextWebSocketFrame: 在netty中,是用于为webSocket专门处理的对象,frame是消息的载体
 *
 * @author liliang
 * @date 2019/10/25.
 */
public class ChatHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    /**
     * 用于记录和管理客户端的 channel
     */
    private static ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        String content = msg.text();
        System.out.println("接收到的客户端"+ ctx.channel().id().asShortText() +"的数据: " + content);
        DataContent dataContent = JSON.parseObject(content, DataContent.class);
        Channel currentChannel = ctx.channel();
        ChatMsg chatMsg = dataContent.getChatMsg();
        if (dataContent.getAction().equals(MsgActionEnum.CONNECT.getType())) {
            ChannelRel.put(chatMsg.getSendUserId(), currentChannel);
        } else if (dataContent.getAction().equals(MsgActionEnum.CHAT.getType())) {
            String msgContent = chatMsg.getMsg();
            String acceptUserId = chatMsg.getAcceptUserId();
            Channel acceptChannel = ChannelRel.get(acceptUserId);
            if (acceptChannel != null) {
                acceptChannel = clients.find(acceptChannel.id());
                if (acceptChannel != null) {
                    acceptChannel.writeAndFlush(new TextWebSocketFrame(msgContent));
                }
            } else {
                // 用户离线, 推送到手机导航栏
                System.out.println("sdf");
            }
        }




//        for (Channel channel : clients) {
//            channel.writeAndFlush(new TextWebSocketFrame("[服务器接收到消息: ]" +
//                    LocalDateTime.now() +
//                    ",消息为: " + content));
//        }

//        clients.writeAndFlush(new TextWebSocketFrame("[服务器接收到消息: ]" +
//                LocalDateTime.now() +
//                ",消息为: " + content));
    }

    /**
     * 当客户端连接服务器之后,
     * 获取客户端的 Channel,并且放到 ChannelGroup 中管理
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        clients.add(ctx.channel());
        System.out.println("客户端连接,channel 长 ID:" + ctx.channel().id().asLongText());
        System.out.println("客户端连接,channel 短 ID:" + ctx.channel().id().asShortText());
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        // 当触发handlerRemoved方法之后,ChannelGroup会自动移除相对应的客户端 Channel
        clients.remove(ctx.channel());
        System.out.println("客户端断开,channel 长 ID:" + ctx.channel().id().asLongText());
        System.out.println("客户端断开,channel 短 ID:" + ctx.channel().id().asShortText());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        // 发生异常之后关闭连接
        ctx.channel().close();
        clients.remove(ctx.channel());
    }
}
